home *** CD-ROM | disk | FTP | other *** search
- /* GRAPHIC LISP */
- /* Scritto nel 1991-94 da Zoia Andrea Michele */
- /* Via Pergola #1 Tirano (SO) Tel. 0342-704210 */
- /* file clos_cl2.c */
-
- #include "clos.h"
-
-
-
- node make_precedence_list();
- void make_prec_aux_u2jl2r();
-
- void lf_mkinstance LF_PARAMS
- {
- /* sintassi (mkinstance nomeclasse {initarg initvalue}*) */
- /* si ritorna un nodo-classe che punta ad una lista */
- /* lista->( (prec_list) (fields 1) ... (fields n)) */
- node prec_list;
- node curr_class;
- node class_list;
- node cl_last;
- node field_list=NIL;
- node fl_last;
- node tmp;
- node curr_initf;
- node curr_inita;
-
- if(IS_CONS(nin)){
- eval(CONSLEFT(nin),nout,genv,lenv,EVAL_SETF);
- if(nout->type==P_VALUE || nout->type==P_UNBOUNDVALUE){
- /* nout->node e' sicuramente un nome */
- if(HAS_CLASS(nout->node)){
-
- /* CLASS(nout->node)= ( (supers) (initforms) (initargs) ) */
-
- prec_list=make_precedence_list(nout->node);
- /* prec_list=lista di precedenze */
- TYPE(cl_last=class_list=node_make())|=NT_IS_CONS;
- CONSLEFT(cl_last)=prec_list;
- CONSRIGHT(cl_last)=NIL;
- /* class_list=( prec_list ) */
- /* ora:per ogni elemento di prec_list si scorre nin per */
- /* cercare eventuali initargs e si alloca una fields_list */
-
- for(;;){
- if(CONSLEFT(prec_list)==T)break;
- curr_class=CLASS(CONSLEFT(prec_list));
- curr_initf=CONSLEFT(CONSRIGHT(curr_class));
- curr_inita=CONSLEFT(CONSRIGHT(CONSRIGHT(curr_class)));
- field_list=NIL;
-
- while(IS_CONS(curr_initf)){
- tmp=CONSRIGHT(nin);
- while(IS_CONS(tmp)){
- if(!IS_CONS(CONSRIGHT(tmp)))
- error(E_FEWARGS,ERR_MERROR|ERR_PNODE|ERR_TBLVL,&nin);
-
- if(CONSLEFT(tmp)==CONSLEFT(curr_inita)){
- eval(CONSLEFT(CONSRIGHT(tmp)),nout,genv,lenv,EVAL_NORM);
- break;
- }
- if(IS_VALUE(CONSLEFT(tmp))&&IS_VALUE(CONSLEFT(curr_inita))&&
- GET_VTYPE(CONSLEFT(tmp))==GET_VTYPE(CONSLEFT(curr_inita))&&
- NODE(CONSLEFT(tmp))==NODE(CONSLEFT(curr_inita)) ){
- eval(CONSLEFT(CONSRIGHT(tmp)),nout,genv,lenv,EVAL_NORM);
- break;
- }
- tmp=CONSRIGHT(CONSRIGHT(tmp));
- }
- if(!IS_CONS(tmp))
- eval(CONSLEFT(curr_initf),nout,genv,lenv,EVAL_NORM);
- if(field_list==NIL){
- field_list=fl_last=node_make();
- }else{
- CONSRIGHT(fl_last)=node_make();
- fl_last=CONSRIGHT(fl_last);
- }
- TYPE(fl_last)|=NT_IS_CONS;
- CONSLEFT(fl_last)=calc_pointer(nout);
- CONSRIGHT(fl_last)=NIL;
-
- curr_initf=CONSRIGHT(curr_initf);
- curr_inita=CONSRIGHT(curr_inita);
- }
- CONSRIGHT(cl_last)=node_make();
- cl_last=CONSRIGHT(cl_last);
- TYPE(cl_last)|=NT_IS_CONS;
- CONSLEFT(cl_last)=field_list;
- CONSRIGHT(cl_last)=NIL;
-
- prec_list=CONSRIGHT(prec_list);
- }
- TYPE(nout->node=node_make())|=NT_IS_VALUE+NT_CLASS;
- CLASS_INSTANCE(nout->node)=class_list;
- nout->type=P_ALLNODE;
- return;
- }
- }
- error(E_BADARGS,ERR_MERROR|ERR_PNODE|ERR_TBLVL,&nout->node);
- }
- error(E_FEWARGS,ERR_MERROR|ERR_PNODE|ERR_TBLVL,&nin);
- }
-
- node make_precedence_list(classname)
- node classname;
- {
- /* data classname si crea la sua lista delle precedenze */
- node n=node_make();
- TYPE(n)|=NT_IS_CONS;
- CONSLEFT(n)=NIL;
- CONSRIGHT(n)=NIL;
- make_prec_aux_u2jl2r(classname,n);
- return CONSRIGHT(n);
- }
-
- void make_prec_aux_u2jl2r(cname,list)
- node cname;
- node list;
- {
- /* ALGORITMO LEFT-TO-RIGHT & UP-TO-JOIN */
- /* cerca cname in list */
- /* scorrendo comunque tutta la lista */
- /* se trova cname nella lista lo sposta in fondo (UP-TO-JOIN) */
- /* se non lo trova lo mette in fondo comunque */
- /* NB:list inizia con un cons vuoto per facilitare tutte le operazioni */
- node curr;
- node prec;
- node node_found;
- int found;
-
- curr=CONSRIGHT(list);
- prec=list;
- found=FALSE;
- while(IS_CONS(curr)){
- if(cname==CONSLEFT(curr)){
- found=TRUE;
- node_found=curr;
- /* elimina il cons contenente cname */
- CONSRIGHT(prec)=CONSRIGHT(curr);
- curr=CONSRIGHT(curr);
- /* chiudi il cons estratto dalla lista */
- CONSRIGHT(node_found)=NIL;
- }else{
- prec=curr;
- curr=CONSRIGHT(curr);
- }
- }
- if(found){
- /* si mette node_found in fondo alla lista list */
- CONSRIGHT(prec)=node_found;
- }else{
- /* si alloca un nuovo cons in fondo alla lista */
- /* si fa insomma (append list (cname)) */
- CONSRIGHT(prec)=node_make();
- TYPE(prec=CONSRIGHT(prec))|=NT_IS_CONS;
- CONSLEFT(prec)=cname;
- CONSRIGHT(prec)=NIL;
- }
-
- /* si scorrono le superclassi di cname da sinistra a destra (LEFT-TO-RIGHT)*/
- cname=CONSLEFT(CLASS(cname));
- while(IS_CONS(cname)){
- make_prec_aux_u2jl2r(CONSLEFT(cname),list);
- cname=CONSRIGHT(cname);
- }
- }
-
-
-
-
-
-
- void _lf_defmethod LF_PARAMS
- {
- node func;
- node fn;
-
- if(nin==NIL)
- error(E_FEWARGS,ERR_MERROR|ERR_PNODE|ERR_TBLVL,&NIL);
- if(!IS_CONS(nin))
- error(E_BADLIST,ERR_MERROR|ERR_PNODE|ERR_TBLVL,&nin);
-
- eval(CONSLEFT(nin),nout,genv,lenv,EVAL_SETF);
-
- /* nout->node e' il nome della funzione */
- if(!IS_NAME(func=nout->node))
- error(E_BADARGS,ERR_MERROR|ERR_PNODE|ERR_TBLVL,&func);
-
- lf_lambda(CONSRIGHT(nin),nout,genv,lenv,EVAL_NORM);
-
- /* si controlla se func e' gia' un metodo */
- if(HAS_FUNCTION(func)&&IS_VALUE(FUNCTION(func))&&
- GET_VTYPE(FUNCTION(func))==NT_METHOD){
- TYPE(fn=node_make())|=NT_IS_CONS;
- CONSLEFT(fn)=FUNCTION(nout->node);
- CONSRIGHT(fn)=METHOD(FUNCTION(func));
- METHOD(FUNCTION(func))=fn;
- return;
- }
- /* fn non e' un metodo */
- TYPE(func)|=NT_HAS_FUNCTION;
- TYPE(fn=node_make())|=NT_IS_CONS;
- CONSLEFT(fn)=FUNCTION(nout->node);
- CONSRIGHT(fn)=NIL;
- TYPE(FUNCTION(func)=node_make())|=NT_IS_VALUE+NT_METHOD;
- METHOD(FUNCTION(func))=fn;
- }
-
-
- void lf_defmethod LF_PARAMS
- {
- node fn,fun;
-
- /* sintassi (defmethod nome <lambda-form>) */
-
- if(IS_CONS(nin)){
- if(!IS_NAME(fn=CONSLEFT(nin))){
- /* se ''nome,, non e' un nome ma una s-espressione allora la valuta */
- eval(fn,nout,genv,lenv,EVAL_SETF);
- /* si controlla se nout e' un nome */
- if(!IS_NAME(nout->node))
- error(E_BADARGS,ERR_MERROR|ERR_PNODE|ERR_TBLVL,&fn);
- fn=nout->node;
- }
- lf_lambda(CONSRIGHT(nin),nout,genv,lenv,EVAL_NORM);
-
- /* si controlla se func e' gia' un metodo */
- if(HAS_FUNCTION(fn)&&IS_VALUE(FUNCTION(fn))&&
- GET_VTYPE(FUNCTION(fn))==NT_METHOD){
- TYPE(fun=node_make())|=NT_IS_CONS;
- CONSLEFT(fun)=FUNCTION(nout->node);
- CONSRIGHT(fun)=METHOD(FUNCTION(fn));
- METHOD(FUNCTION(fn))=fun;
- return;
- }
- /* fn non e' un metodo */
- TYPE(fn)|=NT_HAS_FUNCTION;
- TYPE(fun=node_make())|=NT_IS_CONS;
- CONSLEFT(fun)=FUNCTION(nout->node);
- CONSRIGHT(fun)=NIL;
- TYPE(FUNCTION(fn)=node_make())|=NT_IS_VALUE+NT_METHOD;
- METHOD(FUNCTION(fn))=fun;
- return;
- }
- error(E_FEWARGS,ERR_MERROR|ERR_PNODE|ERR_TBLVL,&nin);
- }
-
-
-
-
-
-
-
-
-
-
-
-
-
-